#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#define N 20
using namespace std;

int t, n, cnt;  // t表示目标和； n表示输入的整数的个数； cnt若是0表示没有找到方案，若是1表示找到了方案
int a[N], b[N]; // a数组表示，要求存入的n个数；b数组表示答案的数组，数组的元素按顺序输出就是一种方案

void dfs(int ai, int bi, int sum) // ai表示在a数组中的下一个要加入b数组中的数下标值， bi是当前求b数组的长度，sum是当前的b数组个元素之和。
{
    if (sum > t) // 如果b数组的和以大于目标和t，则不用再往下找了，这种方案不适合；
        return;
    if (sum == t) // 满足题意的方案
    {
        cnt = 1;                     // 标记是否找到了方案，这样为判断是否输出"NONE"提供了依据；
        for (int i = 0; i < bi; i++) // 方案的输出
        {
            if (i)
            {
                printf("+%d", b[i]);
            }
            else
                printf("%d", b[i]);
        }
        cout << endl;
        return; // 一定要有，（不然浪费时间，去运行下面的for循环了），既然这种情况都满足，就不必再往下找了，只有在sum小于t的情况才往下找
    }
    for (int i = ai; i < n; i++) // 由于sum小于t，继续往下找不断的添加b数组中的值，使其sum达到前两种情况，（这一小点是整个题目的核心）
    {
        b[bi] = a[i];                   // 往b数组中值，此时就可以看出为什么要传ai,bi这些下标参数;
        dfs(i + 1, bi + 1, sum + a[i]); // 寻找下一个下标情况
        while (a[i] == a[i + 1])        // 这是排出重复的过程，（如果不懂为什么：首先考虑什么情况下上面一段dfs(i + 1, bi + 1, sum+a[i]) 执行结束，开始执行之一段？
        {                               // 只有在满足条件sum大于t 或者 sum等于t 才会dfs()函数返回，大于的情况的本来不适合则直接跳过所有相同的，这样可以省时间；等于的
            i++;                        // 情况若不跳过，则这次dfs（）深搜下去后的结果，不就与上次的相同了吗？所以去掉，跳过相同的。这里还有许多细节没有阐述，不再赘述多体会，加油）
        }
    }
    return;
}

int cmp(int a, int b)
{
    return a > b;
}

int main()
{
    while (~scanf("%d%d", &t, &n))
    {
        cnt = 0;
        if (t == 0 && n == 0)
            break;
        for (int i = 0; i < n; i++)
        {
            scanf("%d", &a[i]);
        }
        sort(a, a + n, cmp); // 降序排列
        printf("Sums of %d:\n", t);
        dfs(0, 0, 0);
        if (!cnt)
        {
            printf("NONE\n");
        }
    }
    return 0;
}
